home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / comms / other / slrn / slrn_src / src / util.c < prev    next >
C/C++ Source or Header  |  1999-05-14  |  11KB  |  617 lines

  1. /* Copyright (c) 1998 John E. Davis (davis@space.mit.edu)
  2.  *
  3.  * This file is part of slrn.
  4.  *
  5.  * Slrn is free software; you can redistribute it and/or modify it
  6.  * under the terms of the GNU General Public License as published by the
  7.  * Free Software Foundation; either version 2, or (at your option) any
  8.  * later version.
  9.  * 
  10.  * Slrn is distributed in the hope that it will be useful, but WITHOUT
  11.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13.  * for more details.
  14.  * 
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with Slrn; see the file COPYING.  If not, write to the Free
  17.  * Software Foundation, 59 Temple Place - Suite 330, 
  18.  * Boston, MA  02111-1307, USA.
  19.  */
  20.  
  21. #include "config.h"
  22.  
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <errno.h>
  26. #ifdef HAVE_STDLIB_H
  27. # include <stdlib.h>
  28. #endif
  29.  
  30. #ifdef HAVE_UNISTD_H
  31. # include <unistd.h>
  32. #endif
  33.  
  34. #ifndef VMS
  35. # include <sys/types.h>
  36. # include <sys/stat.h>
  37. #else
  38. # include "vms.h"
  39. #endif
  40.  
  41. #include <slang.h>
  42. #include "jdmacros.h"
  43.  
  44. #include "util.h"
  45. #include "ttymsg.h"
  46.  
  47.  
  48. /* This function allows NULL as a parameter. This fact _is_ exploited */
  49. char *slrn_skip_whitespace (char *b) /*{{{*/
  50. {
  51.    register char ch;
  52.    
  53.    if (b == NULL) return NULL;
  54.  
  55.    while (((ch = *b) == ' ') || (ch == '\t') || (ch == '\n'))
  56.      b++;
  57.    return b;
  58. }
  59.  
  60. /*}}}*/
  61.  
  62. /* returns a pointer to the end of the string */
  63. char *slrn_trim_string (char *smin) /*{{{*/
  64. {
  65.    register char *s, ch;
  66.    
  67.    if (smin == NULL) return NULL;
  68.    s = smin + strlen (smin);
  69.    
  70.    while (s > smin)
  71.      {
  72.     s--;
  73.     ch = *s;
  74.     if ((ch == ' ')
  75.         || (ch == '\n')
  76.         || (ch == '\t'))
  77.       {
  78.          *s = 0;
  79.          continue;
  80.       }
  81.     
  82.     s++;
  83.     break;
  84.      }
  85.    return s;
  86. }
  87.  
  88. /*}}}*/
  89.  
  90. char *slrn_strchr (char *s, char ch) /*{{{*/
  91. {
  92.    register char ch1;
  93.    
  94.    while (((ch1 = *s) != 0) && (ch != ch1)) s++;
  95.    if (ch1 == 0) return NULL;
  96.    return s;
  97. }
  98.  
  99. /*}}}*/
  100.  
  101. /* Search for characters from list in string str.  If found, return a pointer
  102.  * to the first occurrence.  If not found, return NULL. */
  103. char *slrn_strbrk (char *str, char *list) /*{{{*/
  104. {
  105.    char ch, ch1, *p;
  106.    
  107.    while ((ch = *str) != 0)
  108.      {
  109.     p = list;
  110.     while ((ch1 = *p) != 0)
  111.       {
  112.          if (ch == ch1) return str;
  113.          p++;
  114.       }
  115.     str++;
  116.      }
  117.    return NULL;
  118. }
  119.  
  120. /*}}}*/
  121.  
  122. char *slrn_simple_strtok (char *s, char *chp) /*{{{*/
  123. {
  124.    static char *s1;
  125.    char ch = *chp;
  126.    
  127.    if (s == NULL)
  128.      {
  129.     if (s1 == NULL) return NULL;
  130.     s = s1;
  131.      }
  132.    else s1 = s;
  133.    
  134.    while (*s1 && (*s1 != ch)) s1++;
  135.    
  136.    if (*s1 == 0)
  137.      {
  138.     s1 = NULL;
  139.      }
  140.    else *s1++ = 0;
  141.    return s;
  142. }
  143.  
  144. /*}}}*/
  145.  
  146.  
  147. /* Note!!!  These routines assume a flat address space !! */
  148.  
  149. int slrn_case_strncmp (unsigned char *a, register unsigned char *b, register unsigned int n) /*{{{*/
  150. {
  151.    register unsigned char cha, chb, *bmax;
  152.    register int diff = a - b;
  153.    
  154.    bmax = b + n;
  155.    while (b < bmax)
  156.      {
  157.     cha = UPPER_CASE(b[diff]);
  158.     chb = UPPER_CASE(*b);
  159.     if (cha != chb)
  160.       {
  161.          return (int) cha - (int) chb;
  162.       }
  163.     else if (chb == 0) return 0;
  164.     b++;
  165.      }
  166.    return 0;
  167. }
  168.  
  169. /*}}}*/
  170.  
  171. int slrn_case_strcmp (unsigned char *a, register unsigned char *b) /*{{{*/
  172. {
  173.    register unsigned char cha, chb;
  174.    register int diff = a - b;
  175.    
  176.    while (1)
  177.      {
  178.     cha = UPPER_CASE(b[diff]);
  179.     chb = UPPER_CASE(*b);
  180.     if (cha != chb)
  181.       {
  182.          return (int) cha - (int) chb;
  183.       }
  184.     else if (chb == 0) break;
  185.     b++;
  186.      }
  187.    return 0;
  188. }
  189.  
  190. /*}}}*/
  191.  
  192. #if defined(IBMPC_SYSTEM)
  193. void slrn_os2_convert_path (char *path)
  194. {
  195.    char ch;
  196.    while ((ch = *path) != 0)
  197.      {
  198.     if (ch == '/') *path = SLRN_PATH_SLASH_CHAR;
  199.     path++;
  200.      }
  201. }
  202. #endif
  203.  
  204. #ifdef SLRN_USE_OS2_FAT
  205. void slrn_os2_make_fat (char *file, char *name, char *ext)
  206. {
  207.    static char drive[3] = " :";
  208.    char fsys[5];
  209.  
  210.    strcpy (file, name);
  211.    if (isalpha(file[0]) && (file[1] == ':'))
  212.      drive[0] = file[0];
  213.    else
  214.      drive[0] = _getdrive();
  215.  
  216.    if ((0 == _filesys (drive, fsys, sizeof (fsys)))
  217.        && (0 == stricmp (fsys, "FAT")))
  218.      {
  219.     /* FAT */
  220.     _remext (file);                      /* Remove the extension */
  221.      }
  222.  
  223.    strcat (file, ext);
  224. }
  225. #endif
  226.  
  227. static void fixup_path (char *path) /*{{{*/
  228. {
  229. #ifndef VMS
  230.    unsigned int len;
  231.    
  232.    len = strlen (path);
  233.    if (len == 0) return;
  234. # ifdef IBMPC_SYSTEM
  235.    slrn_os2_convert_path (path);
  236. # endif
  237.    if (path[len - 1] == SLRN_PATH_SLASH_CHAR) return;
  238.    path[len] = SLRN_PATH_SLASH_CHAR;
  239.    path[len + 1] = 0;
  240. #endif
  241. }
  242.  
  243. /*}}}*/
  244.  
  245. /* dir and file could be the same in which case this performs a strcat. 
  246.  * If name looks like an absolute path, it will be returned.
  247.  */
  248. int slrn_dircat (char *dir, char *name, char *file)
  249. {
  250.    unsigned int len = 0;
  251.    
  252.    if (name != NULL) 
  253.      {
  254.     if (slrn_is_absolute_path (name))
  255.       {
  256.          strcpy (file, name);
  257. #if defined(IBMPC_SYSTEM)
  258.          slrn_os2_convert_path (file);
  259. #endif
  260.          return 0;
  261.       }
  262.     
  263.     len = strlen (name);
  264.      }
  265.    
  266.    if (dir != NULL) len += strlen (dir);
  267.    
  268.    len += 2;                   /* for / and \0 */
  269.    if (len > SLRN_MAX_PATH_LEN)
  270.      {
  271.     slrn_error ("File name too long.");
  272.     return -1;
  273.      }
  274.    
  275.    if (dir != NULL) 
  276.      {
  277.     if (dir != file) strcpy (file, dir);
  278.     fixup_path (file);
  279.      }
  280.    else *file = 0;
  281.  
  282.    if (name != NULL) strcat (file, name);
  283. #if defined(IBMPC_SYSTEM)
  284.    slrn_os2_convert_path (file);
  285. #endif
  286.    return 0;
  287. }
  288.  
  289. /*{{{ Memory Allocation Routines */
  290.  
  291. static char *do_malloc_error (int do_error)
  292. {
  293.    if (do_error) slrn_error ("Memory allocation failure.");
  294.    return NULL;
  295. }
  296.  
  297. char *slrn_safe_strmalloc (char *s) /*{{{*/
  298. {
  299.    s = SLmake_string (s);
  300.    if (s == NULL) slrn_exit_error ("Out of memory.");
  301.    return s;
  302. }
  303.  
  304. /*}}}*/
  305.  
  306. char *slrn_strnmalloc (char *s, unsigned int len, int do_error)
  307. {
  308.    s = SLmake_nstring (s, len);
  309.    
  310.    if (s == NULL)
  311.      return do_malloc_error (do_error);
  312.    
  313.    return s;
  314. }
  315.  
  316. char *slrn_strmalloc (char *s, int do_error)
  317. {
  318.    if (s == NULL) return NULL;
  319.    return slrn_strnmalloc (s, strlen (s), do_error);
  320. }
  321.  
  322.  
  323. char *slrn_malloc (unsigned int len, int do_memset, int do_error)
  324. {   
  325.    char *s;
  326.    
  327.    s = (char *) SLmalloc (len);
  328.    if (s == NULL)
  329.      return do_malloc_error (do_error);
  330.  
  331.    if (do_memset)
  332.      memset (s, 0, len);
  333.    
  334.    return s;
  335. }
  336.  
  337. char *slrn_realloc (char *s, unsigned int len, int do_error)
  338. {
  339.    if (s == NULL)
  340.      return slrn_malloc (len, 0, do_error);
  341.    
  342.    s = SLrealloc (s, len);
  343.    if (s == NULL)
  344.      return do_malloc_error (do_error);
  345.     
  346.    return s;
  347. }
  348.  
  349. char *slrn_safe_malloc (unsigned int len)
  350. {
  351.    char *s;
  352.    
  353.    s = slrn_malloc (len, 1, 0);
  354.  
  355.    if (s == NULL)
  356.      slrn_exit_error ("Out of memory");
  357.    
  358.    return s;
  359. }
  360.  
  361. void slrn_free (char *s)
  362. {
  363.    if (s != NULL) SLfree (s);
  364. }
  365.  
  366. /*}}}*/
  367.  
  368. char *slrn_fix_regexp (char *pat) /*{{{*/
  369. {
  370.    static char newpat[256];
  371.    char *p, ch;
  372.    unsigned int len;
  373.  
  374.    len = 1;                   /* For ^ */
  375.    p = pat;
  376.    while (*p != 0)
  377.      {
  378.     if ((*p == '.') || (*p == '*') || (*p == '+')) len++;
  379.     len++;
  380.     p++;
  381.      }
  382.    len++;                   /* for $ */
  383.    len++;                   /* for \0 */
  384.  
  385.    if (len > sizeof(newpat))
  386.      slrn_exit_error ("Pattern too long for buffer");
  387.      
  388.    p = newpat;
  389.  
  390.    *p++ = '^';
  391.    while ((ch = *pat++) != 0)
  392.      {
  393.     if ((ch == '.') || (ch == '+'))
  394.       *p++ = '\\';
  395.     else if (ch == '*')
  396.       *p++ = '.';
  397.  
  398.     *p++ = ch;
  399.      }
  400.    
  401.    if (*(p - 1) != '$') 
  402.      *p++ = '$';
  403.  
  404.    *p = 0;
  405.  
  406.    return newpat;
  407. }
  408.  
  409. /*}}}*/
  410.  
  411. int slrn_is_absolute_path (char *path)
  412. {
  413.    if (path == NULL)
  414.      return 0;
  415.  
  416.    if (*path == SLRN_PATH_SLASH_CHAR)
  417.      return 1;
  418. #if defined(IBMPC_SYSTEM)
  419.    if (*path == '/')
  420.      return 1;
  421.    if (*path && (path[1] == ':'))
  422.      return 1;
  423. #endif
  424.    return 0;
  425. }
  426.  
  427.  
  428. /* This is like slrn_dircat except that any dots in name can get mapped to
  429.  * slashes.  It also mallocs space for the resulting file.
  430.  */
  431. char *slrn_spool_dircat (char *root, char *name, int map_dots)
  432. {
  433.    char *spool_group, *p, ch;
  434.    unsigned int len;
  435.  
  436.    len = strlen (root);
  437.  
  438.    spool_group = SLmalloc (strlen (name) + len + 2);
  439.    if (spool_group == NULL)
  440.      {
  441.     slrn_exit_error ("Out of memory.");
  442.      }
  443.  
  444.    strcpy (spool_group, root);
  445.  
  446.    p = spool_group + len;
  447.    if (len && (*(p - 1) != SLRN_PATH_SLASH_CHAR))
  448.      *p++ = SLRN_PATH_SLASH_CHAR;
  449.